home *** CD-ROM | disk | FTP | other *** search
- #import "IRCTask.h"
- #import "poker.h"
-
- @implementation IRCTask
-
- + (id)sharedIRCTask {
- static IRCTask *task = nil;
- if (task == nil) {
- task = [[IRCTask alloc] init];
- }
- return task;
- }
-
- #define IRC_EXECUTABLE [[NSBundle mainBundle] pathForResource:@"irc" ofType:@""]
-
- - (void)pushStringOverWire:(const char *)buf {
- [[to_irc fileHandleForWriting] writeData:[NSData dataWithBytes:buf length:strlen(buf)]];
- }
-
- - (void)stringToTBot:(const char *)buf {
- [self pushStringOverWire:[[NSString stringWithFormat:@"/msg tbot p %s\n",buf]cString]];
- }
-
- - (void)returnFromVacation {
- [self stringToTBot:"back"];
- }
-
- - (void)goOnVacation {
- [self stringToTBot:"vacation"];
- }
-
- - (void)bet:(int)amount {
- [self stringToTBot:[[NSString stringWithFormat:@"raise %d",amount]cString]];
- }
-
- - (void)minBet {
- [self stringToTBot:"TODO"];
- }
-
- - (void)pushAllIn {
- [self stringToTBot:"raise 2000000"];
- }
-
- - (void)call {
- [self stringToTBot:"call"];
- }
-
- - (void)fold {
- [self stringToTBot:"fold"];
- }
-
- - (void)halfPot {
- [self stringToTBot:"TODO"];
- }
-
- - (int)pot {
- [self stringToTBot:"raise pot"];
- return 0;
- }
-
- - (void)leaveTable{
- [self stringToTBot:"quit"];
- }
-
- - (void)joinTable{
- [self pushStringOverWire:"/join #tourney\n"];
- [self stringToTBot:"join i"];
- }
-
-
- - (Card *)cardFromRankChar:(char)rank_char suitChar:(char)suit_char
- {
- const char *suits = "Xcshd";
- const char *ranks = "AKQJT98765432";
- Card *retval;
- Suit s;
- Rank r;
- char *sp;
- char *rp;
-
- s = 0;
- r = 0;
- sp = strchr (suits, suit_char);
- rp = strchr (ranks, rank_char);
- if (sp && rp)
- {
- s = sp - suits;
- r = rp - ranks;
- }
- retval = [Card cardWithSuit:s rank:r];
- return retval;
- }
-
- #define TRY_TO_MATCH(sscanf_call, n_expected, method_call) \
- do \
- if (sscanf sscanf_call == n_expected) \
- { \
- method_call; \
- goto SUCCESS; \
- } \
- while (FALSE)
-
- -(void) addPlayerHelper:(const char *) player cash:(int) amount char1:(char) c1 char2:(char)c2
- {
- BOOL is_vaced;
- BOOL is_button;
- Player *p = [pokerTable findPlayerWithName:player];
- [pokerTable addPlayer:player cash:amount];
- is_vaced = c1 == 'V';
- is_button = (c1 == 'B') || (c2 == 'B');
- [p setOnVacation:is_vaced];
- if (is_button) [pokerTable setButtonPlayer:player];
-
- }
-
- - (BOOL) parseLine:(NSData *)line
- {
- char *buf, *orig_buf;
- char *player;
- int n_players;
- BOOL retval;
- int nleft;
- char bang, dot;
- int small_blind;
- int big_blind;
- int blind_remaining;
- char *blind_remaining_units;
- int hand_no;
- int blind;
- int pot;
- int to_call;
- int amount;
- char *by_whom;
- char r1, r2, r3, r4, r5;
- char s1, s2, s3, s4, s5;
- char colon;
- char *hand_string;
- char *message_from;
- volatile BOOL is_public;
-
- buf = alloca ([line length] + 1);
- [line getBytes:buf];
- buf[[line length]] = 0;
- orig_buf = buf;
-
- /* strip portion that shows this coming from TBot */
- if (buf[0] != '<' && buf[0] != '-' && buf[0] != '*')
- return FALSE;
- else
- {
- char desired;
-
- desired = ( buf[0] == '<') ? '>' : buf[0];
- buf = strchr (buf+1, ' ');
- if (!buf || buf[-1] != desired)
- return FALSE;
- else
- {
- int len;
-
- --buf;
- len = buf - orig_buf - 1;
- if (len <= 0)
- return FALSE;
- message_from = alloca (len + 1);
- memcpy (message_from, orig_buf+1, len);
- message_from[len] = 0;
- buf += 2;
- is_public = orig_buf[0] == '<';
- }
- }
-
- player = alloca ([line length] + 1);
- blind_remaining_units = alloca ([line length] + 1);
- by_whom = alloca ([line length] + 1);
- hand_string = alloca ([line length] + 1);
- retval = TRUE;
-
- if (strcmp (message_from, "TBot") != 0) {
- [pokerTable player:message_from messages:buf];
- return TRUE;
- }
-
- #if 0
- TRY_TO_MATCH
- (
- (buf, "%s has joined the game. We now have %d players.", player, &nleft), 2,
- [pokerTable addPlayer:player cash:5000]);
- #endif
-
- TRY_TO_MATCH
- (
- (buf, "%s quits. We now have %d players.", player, &nleft), 2,
- [pokerTable playerQuits:player n_left:nleft]);
-
- TRY_TO_MATCH
- (
- (buf, "Tourney started by %s!", player), 1,
- [pokerTable readyToBeginGame]);
-
- TRY_TO_MATCH
- (
- (buf, "The blinds are currently $%d and $%d.", &small_blind, &big_blind), 2,
- [pokerTable blindsAre:small_blind and:big_blind]);
-
- TRY_TO_MATCH
- (
- (buf, "Blinds will double in %d %s.", &blind_remaining, blind_remaining_units), 2,
- [pokerTable blindsWillDoubleIn:blind_remaining units:blind_remaining_units]);
-
- TRY_TO_MATCH
- (
- (buf, "Game #%d, %d players. Dealing Holdem high", &hand_no, &n_players), 2,
- [pokerTable beginAddingPlayers]);
-
- TRY_TO_MATCH
- (
- (buf, "%s blinds $%d. Pot is now $%d.", player, &blind, &pot), 3,
- [pokerTable player:player blinds:blind potNow:pot allIn:NO]);
-
- TRY_TO_MATCH
- (
- (buf, "%s blinds $%d and is all in. Pot is now $%d.", player, &blind, &pot), 3,
- [pokerTable player:player blinds:blind potNow:pot allIn:YES]);
-
- TRY_TO_MATCH
- (
- (buf, "%s is next to act. (%d to call)", player, &to_call), 2,
- [pokerTable player:player toCall:to_call]);
-
- TRY_TO_MATCH
- (
- (buf, "%s folds. We now have %d players in the hand.", player, &n_players), 2,
- [pokerTable player:player foldsLeaving:n_players]);
-
- TRY_TO_MATCH
- (
- (buf, "%s calls $%d. Pot is now $%d.", player, &amount, &pot), 3,
- [pokerTable player:player calls:amount potNow:pot allIn:NO]);
-
- TRY_TO_MATCH
- (
- (buf, "%s calls $%d and is all in. Pot is now $%d.", player, &amount, &pot), 3,
- [pokerTable player:player calls:amount potNow:pot allIn:YES]);
-
- TRY_TO_MATCH
- (
- (buf, "%s has sent %s on vacation!", player, by_whom), 2,
- [pokerTable player:player vacationedBy:by_whom]);
-
- TRY_TO_MATCH
- (
- (buf, "%s checks%c", player, &dot), 2,
- [pokerTable playerChecks:player]);
-
- TRY_TO_MATCH
- (
- (buf, "Board: %c%c %c%c %c%c %c%c %c%c", &r1, &s1, &r2, &s2, &r3, &s3, &r4, &s4, &r5, &s5), 10,
- {[pokerTable publicCardNumber:0 didShowCard:[self cardFromRankChar:r1 suitChar:s1]];
- [pokerTable publicCardNumber:1 didShowCard:[self cardFromRankChar:r2 suitChar:s2]];
- [pokerTable publicCardNumber:2 didShowCard:[self cardFromRankChar:r3 suitChar:s3]];
- [pokerTable publicCardNumber:3 didShowCard:[self cardFromRankChar:r4 suitChar:s4]];
- [pokerTable publicCardNumber:4 didShowCard:[self cardFromRankChar:r5 suitChar:s5]];});
-
- TRY_TO_MATCH
- (
- (buf, "Board: %c%c %c%c %c%c %c%c", &r1, &s1, &r2, &s2, &r3, &s3, &r4, &s4), 8,
- {[pokerTable publicCardNumber:0 didShowCard:[self cardFromRankChar:r1 suitChar:s1]];
- [pokerTable publicCardNumber:1 didShowCard:[self cardFromRankChar:r2 suitChar:s2]];
- [pokerTable publicCardNumber:2 didShowCard:[self cardFromRankChar:r3 suitChar:s3]];
- [pokerTable publicCardNumber:3 didShowCard:[self cardFromRankChar:r4 suitChar:s4]];});
-
- TRY_TO_MATCH
- (
- (buf, "Board: %c%c %c%c %c%c", &r1, &s1, &r2, &s2, &r3, &s3), 6,
- {[pokerTable publicCardNumber:0 didShowCard:[self cardFromRankChar:r1 suitChar:s1]];
- [pokerTable publicCardNumber:1 didShowCard:[self cardFromRankChar:r2 suitChar:s2]];
- [pokerTable publicCardNumber:2 didShowCard:[self cardFromRankChar:r3 suitChar:s3]];});
-
- TRY_TO_MATCH
- (
- (buf, "%s bets $%d. Pot is now $%d.", player, &amount, &pot), 3,
- [pokerTable player:player bets:amount potNow:pot allIn:NO]);
-
- TRY_TO_MATCH
- (
- (buf, "%s bets $%d and is all in. Pot is now $%d.", player, &amount, &pot), 3,
- [pokerTable player:player bets:amount potNow:pot allIn:YES]);
-
- TRY_TO_MATCH
- (
- (buf, "%s is back from vacation%c", player, &bang), 2,
- [pokerTable playerBackFromVacation:player]);
-
- TRY_TO_MATCH
- (
- (buf, "%s wins $%d.", player, &amount), 2,
- [pokerTable player:player wins:amount withHand:NULL]);
-
- TRY_TO_MATCH
- (
- (buf, "High: %s wins $%d with %s.", player, &amount, hand_string), 3,
- [pokerTable player:player wins:amount withHand:hand_string]);
-
- TRY_TO_MATCH
- (
- (buf, "Players' hands%c", &colon), 1,
- [pokerTable aboutToShowHands]);
-
- TRY_TO_MATCH
- (
- (buf, "Your hole cards are: %c%c %c%c", &r1, &s1, &r2, &s2), 4,
- [pokerTable userGotFirstHoleCard:[self cardFromRankChar:r1 suitChar:s1]
- secondCard:[self cardFromRankChar:r2 suitChar:s2]]);
-
- TRY_TO_MATCH
- (
- (buf, "%s : %c%c %c%c", player, &r1, &s1, &r2, &s2), 5,
- {Player *p;
- p = [pokerTable findPlayerWithName:player];
- [[p holeHand] setFirstHoleCard:[self cardFromRankChar:r1 suitChar:s1]];
- [[p holeHand] setSecondHoleCard:[self cardFromRankChar:r2 suitChar:s2]];});
-
- TRY_TO_MATCH
- (
- (buf, "%s raises $%d. Pot is now $%d.", player, &amount, &pot), 3,
- [pokerTable player:player raises:amount potNow:pot allIn:NO]);
-
- TRY_TO_MATCH
- (
- (buf, "%s raises $%d and is all in. Pot is now $%d.", player, &amount, &pot), 3,
- [pokerTable player:player raises:amount potNow:pot allIn:YES]);
-
- TRY_TO_MATCH
- (
- (buf, "%s is busted%c", player, &bang), 2,
- [pokerTable playerBusted:player]);
-
- TRY_TO_MATCH
- (
- (buf, "%s has quit%c", player, &dot), 2,
- [pokerTable playerQuit:player]);
-
- if (buf[0] == ' ' || buf[0] == 'V' || buf[0] == 'B')
- {
- char c1, c2;
-
- if (sscanf (buf, "%c%c%s %d", &c1, &c2, player, &amount) == 4)
- {
- [self addPlayerHelper:player cash:amount char1:c1 char2:c2];
- buf = strchr (buf+2, ' ');
- while (*buf == ' ')
- ++buf;
- buf = strchr (buf, ' ');
- #if 0
- while (strncmp (buf, " ", 3) == 0 || (*buf == ' ' && buf[1] != ' '))
- ++buf;
- #else
- buf += 3;
- #endif
- if (sscanf (buf, "%c%c%s %d", &c1, &c2, player, &amount) == 4)
- {
- [self addPlayerHelper:player cash:amount char1:c1 char2:c2];
- buf = strchr (buf+2, ' ');
- while (*buf == ' ')
- ++buf;
- buf = strchr (buf, ' ');
- #if 0
- while (strncmp (buf, " ", 3) == 0 || (*buf == ' ' && buf[1] != ' '))
- ++buf;
- #else
- buf += 3;
- #endif
- if (sscanf (buf, "%c%c%s %d", &c1, &c2, player, &amount) == 4)
- [self addPlayerHelper:player cash:amount char1:c1 char2:c2];
- }
- }
- }
-
- retval = FALSE;
- SUCCESS:
- return retval;
- }
-
-
- - (void) gotSomeData:(NSNotification *)note
- {
- NSData *data;
- const char *start_bytes, *stop_bytes;
- int length;
-
- #warning THIS CODE ASSUMES LINE WONT SPLIT ACROSS DATA
-
- data = [[note userInfo] objectForKey:NSFileHandleNotificationDataItem];
- start_bytes = [data bytes];
- length = [data length];
- stop_bytes = start_bytes;
- while (length > 0)
- {
- while (length > 0 && *stop_bytes != '\n')
- {
- ++stop_bytes;
- --length;
- }
- if (stop_bytes > start_bytes)
- {
- NSData *new_data;
-
- new_data = [NSData dataWithBytes:start_bytes length:stop_bytes - start_bytes];
- [pokerTable setStatusString:[[[NSString alloc]initWithData:new_data encoding:[NSString defaultCStringEncoding]]autorelease]];
- [self parseLine:new_data];
- }
- start_bytes = stop_bytes + 1;
- stop_bytes = start_bytes;
- --length;
- }
- [[from_irc fileHandleForReading] readInBackgroundAndNotify];
- }
-
- - (void)makeIRCConnection:(PokerTable *)table
- {
- NSMutableArray *args = [NSMutableArray array];
- pokerTable = table;
- aTask = [[NSTask alloc] init];
- to_irc = [NSPipe pipe];
- from_irc = [NSPipe pipe];
- #if 1
- [args addObject:@"-d"];
- [args addObject:@"deadhead"];
- [args addObject:@"irc.poker.net"];
- [aTask setLaunchPath:IRC_EXECUTABLE];
- #else
- [args addObject:@"/Local/Users/machack/ctm/poker/tbot2/typescript_FIRST_OFFICIAL_SCORE"];
- [aTask setLaunchPath:@"/bin/cat"];
- #endif
- [aTask setArguments:args];
- [aTask setStandardInput:to_irc];
- [aTask setStandardOutput:from_irc];
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(gotSomeData:)
- name:NSFileHandleReadCompletionNotification object:nil];
-
- [[from_irc fileHandleForReading] readInBackgroundAndNotify];
- [pokerTable newPokerTable];
- [aTask launch];
-
- }
- @end
-